package com.simple.editor.ui;

import com.simple.editor.action.ActionManager;
import com.simple.editor.action.EditorUIAction;
import com.simple.editor.action.EditorException;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * User: vsoroka
 * Date: 05.06.13
 * Time: 10:41
 * To change this template use File | Settings | File Templates.
 */
public class Tab extends JScrollPane {
    private static final Icon CLOSE_TAB_ICON = new ImageIcon(Tab.class.getResource("/tab-close.png"));
    private static final Icon TAB_ICON = new ImageIcon(Tab.class.getResource("/tab_edit.png"));
    private final FileModel file;
    private final ActionManager actionManager;
    private final JPanel pnlTab;
    private final JLabel lblTitle;
    private final JTextArea textArea;

    public Tab(final FileModel file, final ActionManager actionManager) {
        this.file = file;
        this.actionManager = actionManager;

        pnlTab = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0));
        pnlTab.setOpaque(false);

        lblTitle = new JLabel(file.getName());
        lblTitle.setIcon(TAB_ICON);

        final JButton btnClose = new JButton();
        btnClose.setOpaque(false);

        // Configure icon and rollover icon for button
        btnClose.setRolloverIcon(CLOSE_TAB_ICON);
        btnClose.setRolloverEnabled(true);
        btnClose.setIcon(CLOSE_TAB_ICON);

        // Set border null so the button doesn't make the tab too big
        btnClose.setBorder(null);

        // Make sure the button can't get focus, otherwise it looks funny
        btnClose.setFocusable(false);

        // Put the panel together
        pnlTab.add(lblTitle);
        pnlTab.add(btnClose);

        // Add a thin border to keep the image below the top edge of the tab
        // when the tab is selected
        pnlTab.setBorder(BorderFactory.createEmptyBorder(1, 0, 0, 0));

        // Add the listener that removes the tab
        final ActionListener listener = new ActionListener() {
            @Override
            public void actionPerformed(final ActionEvent e) {
                actionManager.runAction(EditorUIAction.Type.CLOSE, Tab.this.file);
            }
        };
        btnClose.addActionListener(listener);

        final AbstractAction closeTabAction = new AbstractAction() {
            @Override
            public void actionPerformed(final ActionEvent e) {
                actionManager.runAction(EditorUIAction.Type.CLOSE, Tab.this.file);
            }
        };


        final KeyStroke controlW = KeyStroke.getKeyStroke("control W");
        final InputMap inputMap = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);

        inputMap.put(controlW, "closeTab");
        getActionMap().put("closeTab", closeTabAction);
        final AbstractAction saveTabAction = new

                AbstractAction() {
                    @Override
                    public void actionPerformed(final ActionEvent e) {
                        actionManager.runAction(EditorUIAction.Type.SAVE, Tab.this.file);
                    }
                };

        final KeyStroke controlS = KeyStroke.getKeyStroke("control S");

        inputMap.put(controlS, "saveTab");
        getActionMap().put("saveTab", saveTabAction);
        textArea = createTextArea();

        setViewportView(textArea);
    }

    private static JTextArea createTextArea() {
        final JTextArea textArea = new JTextArea();
        final Font font = new Font("Verdana", Font.PLAIN, 12);
        textArea.setFont(font);
        textArea.setForeground(Color.DARK_GRAY);
        return textArea;
    }

    public void readFile() throws EditorException {
        FileReader reader = null;
        try {
            reader = new FileReader(file);
            textArea.read(reader, null);
        } catch (IOException ex) {
            throw new EditorException(ex.getMessage(), ex);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }

        textArea.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void insertUpdate(final DocumentEvent e) {
                handleChange();
            }

            @Override
            public void removeUpdate(final DocumentEvent e) {
                handleChange();
            }

            @Override
            public void changedUpdate(final DocumentEvent e) {
                handleChange();
            }

            private void handleChange() {
                if (!file.isChanged()) {
                    file.setChanged(true);
                    actionManager.runAction(EditorUIAction.Type.MODIFY, file);
                }
            }
        });
    }

    public void syncLabelStyle() {
        Utils.updateLabelForTheFile(lblTitle, file);
    }

    public JPanel getPnlTab() {
        return pnlTab;
    }

    public boolean save() throws EditorException {

        if (!file.isChanged()) {
            return false;
        }

        BufferedWriter writer = null;
        try {
            writer = new BufferedWriter(new FileWriter(file, false));
            textArea.write(writer);
            file.setChanged(false);
            lblTitle.setFont(null);
            return true;
        } catch (IOException e) {
            throw new EditorException(e);
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    FileModel getFile() {
        return file;
    }
}
